<?php

class SeedService extends AbstractService
{

    /**
     * @var SeedService
     */
    private static $instance;

    /**
     * Get instance of SeedService.
     *
     * @return SeedService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new SeedService();
        }

        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 处理创建时的逻辑
     *
     * @param int $userId
     * @param int $platformId
     * @return void
     */
    public function handleCreate($userId, $platformId = null)
    {
        $this->handleLevelUp($userId, 1);
    }


    /**
     * 处理登录时的逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {

    }

    /**
     * 提供当前 service 数据
     *
     * @param int $userId
     * @param boolean $visitMode default false
     * @return array(PlantSeedVoList)
     */
    public function info($userId, $visitMode = false)
    {
        $seedList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_PLANT_SEED);
        NewTaskService::get()->setProgress($userId,GameConst::TASK_CULTIVATE,count($seedList->toArray()));
        TreeService::get()->setProgress($userId,GameConst::TREE_TASK_CULTIVATE_FLOWER,count($seedList->toArray()));
        return array(
            $seedList
        );
    }

    /**
     * 获取已经解锁的花id（种子ID）
     * @param int $userId
     * @return array($itemDefId, $itemDefId, ...)
     * @throws SzException
     */
    public function getUnlockFlowerList($userId)
    {
        $seedList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_PLANT_SEED);
        return array_keys($seedList->getList());
    }

    /**
     * 等级解锁种子
     * @param $userId
     * @param $level
     * @return void
     * @throws SzException
     */
    public function handleLevelUp($userId, $level)
    {
        $reqTime = GameService::get()->getReqTime();

        $seedList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_PLANT_SEED);

        $seedSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_SEED_CONDITION, null, true);
        foreach ($seedSettings as $seedId => $seedSetting) {
            $seedVo = $seedList->getElement($seedId, false);
            if ($seedVo) {//已经解锁的不需要判断是否能解锁
                continue;
            }
            //不是条件解锁
            //不到解锁等级
            if ($level < $seedSetting['unlockLv'] || $seedSetting['unlockType'] != 1) {
                continue;
            }
            if ($seedSetting['taskId'] != -1) {
                MissionService::get()->accept($userId, $seedSetting['taskId'], $reqTime);
                continue;
            }
            $seedVo = new PlantSeedVo($userId, $seedId, 0, 0, true);
            $seedList->addElement($seedVo);
            $seedList->setElement($seedId, $seedVo);

            // 数据采集:花卉手册解锁鲜花
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
                'clientData' => array(
                    'tid' => 'Module:book|action:unlock|',
                    'item' => $seedId,
                    'value' => 1
                )
            ));

            // 数据采集:鲜花解锁
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_UPGRADE, array(
                'clientData' => array(
                    'tid' => 'objective:book|item:' . $seedId . '|',
                    'item' => 'fromlevel:|changelev:unlock|targetlev:|',
                    'value' => 1
                )
            ));
            // 更新任务进度---解锁X朵花
            MissionService::get()->progress($userId, GameConst::ENTITY_ACTION_UNLOCK_SEED, GameConst::ENTITY_TYPE_NULL, $seedId, 1);
        }
        SzPersister::get()->setVoList($seedList);
    }

    /**
     * 解锁种子
     * @param int $userId
     * @param int $seedId
     * @return SzAbstractVoList
     */
    public function unlockSeed($userId, $seedId)
    {
        // 解锁
        $seedList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_PLANT_SEED);
        $seedVo = $seedList->getElement($seedId, false);
        if ($seedVo) {
            return $seedList;
        }
        $seedVo = new PlantSeedVo($userId, $seedId, 0, 0, true);
        $seedList->addElement($seedVo);
        $seedList->setElement($seedId, $seedVo);
        if ($_SERVER['is_payment_callback'] ?? false) $seedList->persist();
        SzPersister::get()->setVoList($seedList);

        $seedSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_SEED_CONDITION, $seedId, true);
        if ($seedSetting['taskId'] != -1) {
            MissionService::get()->remove($userId, $seedSetting['taskId'], false);
        }

        // 种子等级排行榜
        SeedService::get()->setFlowerLevel($userId,GameService::get()->getReqTime());

        // 数据采集:花卉手册解锁鲜花
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:book|action:unlock|',
                'item' => $seedId,
                'value' => 1
            )
        ));

        // 数据采集:鲜花解锁
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_UPGRADE, array(
            'clientData' => array(
                'tid' => 'objective:book|item:' . $seedId . '|',
                'item' => 'fromlevel:|changelev:unlock|targetlev:|',
                'value' => 1
            )
        ));
        // 更新任务进度---解锁X朵花
        MissionService::get()->progress($userId, GameConst::ENTITY_ACTION_UNLOCK_SEED, GameConst::ENTITY_TYPE_NULL, $seedId, 1);
        return $seedList;
    }

    /**
     * 完成种子解锁任务
     * @param int $userId
     * @param $missionId
     * @return bool
     * @throws SzException
     */
    public function finishMission($userId, $missionId)
    {
        $taskSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_TASK, $missionId, true);
        if ($taskSetting['taskType'] == GameConst::TASK_TYPE_UNL0CK_SEED) {
            MissionService::get()->finish($userId, $missionId);
        }
        return true;
    }

    /**
     * 获取种子总等级
     * @param int $userId
     * @return int
     * @throws SzException
     */
    public function getSeedTotalLevel($userId)
    {
        $total = 0;
        /**
         * @var PlantSeedVo $seedVo
         */
        $seedList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_PLANT_SEED);
        foreach ($seedList->getList() as $seedId => $seedVo) {
            $total += $seedVo->getLevel() + 1;
        }
        return $total;
    }

    /**
     * 获取当前能培育的种子培育缺少的道具id
     * @param int $userId
     * @return array
     */
    public function getCultivateLackItems($userId)
    {
        /**
         * @var NewCultivateLandVoList $userLandList
         * @var NewCultivateLandVo $userLand
         * @var ModuleItemVoList $itemList
         * @var ModuleProfileVo $profile
         */
        $flowerSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_SEED_CONDITION, null, true);
        $profile = SzPersister::get()->getVo($userId, ModuleProfileConst::ORM_NAME_PROFILE);

        $seedList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_PLANT_SEED);

        $userLandList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_NEW_CULTIVATE_LAND);
        $userLand = $userLandList->getElement(21030001, false);

        $flowerId = 0;
        if ($userLand) {
            $flowerId = $userLand->getFlowerId();
        }

        $items = [];

        $itemList = SzPersister::get()->getVoList($userId, ModuleItemConst::ORM_NAME_ITEM);
        foreach ($flowerSettings as $_flowerId => $setting) {
            if ($flowerId == $_flowerId) {//正在培育中的
                continue;
            }
            if ($profile->getLevel() < $setting['unlockLv']) {//等级未达到
                continue;
            }
            if ($setting['unlockType'] == 4) {
                $item = $itemList->getElementsByItemDefId($setting['taskId']);
                if (is_null($item)) {
                    continue;
                }
            } else if ($setting['unlockType'] != 2) {//不是培育解锁
                continue;
            }
            $seedVo = $seedList->getElement($_flowerId, false);
            if ($seedVo) {//已经解锁
                continue;
            }
            foreach ($setting['itemId'][0] as $entityId => $count) {
                list(, , $itemDefId) = EntityService::get()->parseEntityId($entityId);
                if ($itemList->getItemDefCount($itemDefId) < $count && !in_array($itemDefId, $items)) {
                    $items[] = $itemDefId;
                }
            }
        }
        return $items;
    }

    /**
     * 获取周一日期
     * @param $reqTime
     * @return false|string
     */
    public function getMondayDate($reqTime) {
        $weekday = date('w',$reqTime);
        $weekday = ($weekday + 6) % 7;
        $date = date('Ymd',strtotime("-{$weekday} day",$reqTime));
        return $date;
    }

    /**
     * 获取上周一日期
     * @param $reqTime
     * @return false|string
     */
    public function getLastMondayDate($reqTime) {
        $weekday = date('w',$reqTime);
        $weekday = ($weekday + 6) % 7;
        $weekday += 7;
        $date = date('Ymd',strtotime("-{$weekday} day",$reqTime));
        return $date;
    }

    /**
     * 更新鲜花种子等级
     * @param $userId
     * @param $reqTime
     * @param bool $isShow
     * @param null $redis
     * @return int
     * @throws SzException
     */
    public function setFlowerLevel($userId,$reqTime,$isShow = false,$redis = null) {
        $isUp = 0;

        $level = $this->getSeedTotalLevel($userId);
        $sysConfig = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_SYSTEM_UNLOCK, GameConst::FUNC_FLOWER_LEVEL, true);
        if ($sysConfig['level'] > (UserService::get()->getUserLevel($userId) + 1)) {
            return $isUp;
        }

        if (is_null($redis)) {
            $redis = SzDbFactory::get()->getDb(null, SzAbstractDb::DB_TYPE_REDIS);
        }
        $mondayDate = $this->getMondayDate($reqTime);
        $cacheKey = GameConst::CACHE_KEY_FLOWER_RANK.$mondayDate;

        $userLevel = $redis->zScore($cacheKey,$userId);

        $lastRank = $currentRank = 0;

        if ($isShow) {
            $lastRank = $redis->zRevRank($cacheKey,$userId);
            if ($lastRank === false) {
                $lastRank = 0;
            }
        }

        if (intval($userLevel) != $level) {
            $level += ((9999999999 - $reqTime) / 10000000000);
            $redis->zAdd($cacheKey,$level,$userId);
        }

        if ($isShow) {
            $currentRank = $redis->zRevRank($cacheKey,$userId);
            if ($currentRank < $lastRank) {
                $isUp = 1;
            }
        }
        if (!$redis->ttl($cacheKey) == -1) {
            $redis->expire($cacheKey,1296000); // 设置过期时间为15天
        }

        return $isUp;
    }

    /**
     * 领取上周排行榜信息
     * @param $userId
     * @param $reqTime
     * @return bool
     * @throws SzException
     */
    public function flowerLevelReward($userId,$reqTime) {
        $redis = SzDbFactory::get()->getDb(null, SzAbstractDb::DB_TYPE_REDIS);
        $lastMondayDate = $this->getLastMondayDate($reqTime);

        $rankCacheKey = GameConst::CACHE_KEY_FLOWER_RANK.$lastMondayDate;

        if (!$redis->exists($rankCacheKey)) {
            throw new SzException(90065);
        }
        $rewardCacheKey = GameConst::CACHE_KEY_FLOWER_RANK_REWARD_STATUS.$lastMondayDate;
        if ($redis->hGet($rewardCacheKey,$userId)) {
            throw new SzException(90007);
        }

        $rankListSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_RANK_LIST , null, true);

        $len = count($rankListSettings);
        if (!$len) {
            throw new SzException(80001,GameConst::CONFIG_GAME_RANK_LIST);
        }

        $currentRank = $redis->zRevRank($rankCacheKey,$userId);
        if ($currentRank === false) {
            throw new SzException(90065);
        }

        $currentRank++;

        $reward = array();
        $indexId = 0;
        foreach ($rankListSettings as $rankListSetting) {
            list($min,$max) = $rankListSetting['rank'];
            if ($currentRank >= $min && $currentRank <= $max) {
                $reward = $rankListSetting['reward'];
                $indexId = $rankListSetting['indexId'];
                break;
            }
        }

        if (!$indexId) {
            $reward = $rankListSettings[$len]['reward'];
            $indexId = $rankListSettings[$len]['id'];
        }

        $output = '';
        foreach ($reward as $entityId => $count) {
            GameService::get()->handleEntity($userId, $entityId, $count, true);
            $output .= $entityId.':'.$count.'|';
        }
        CommonFunctionService::get()->reportResourceUseDetails(GameConst::FUNC_FLOWER_LEVEL,$userId,1,$output,'flowerLevelReward');//获得资源上报

        $profileInfoList = SzPersister::get()->getVoList($userId, ModuleProfileConst::ORM_NAME_PROFILE_INFO);
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_FLOWER_LEVEL, $indexId, $profileInfoList);
        $expireTime = strtotime($lastMondayDate) + 86400 * 14; // 周日时间
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_FLOWER_LEVEL_EXPIRE_TIME, $expireTime, $profileInfoList);

        $redis->hSet($rewardCacheKey,$userId,1);
        if ($redis->ttl($rewardCacheKey) == -1) {
            $redis->expire($rewardCacheKey,64800);
        }

        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:rank|action:rank|',
                'item' => $currentRank.'&'.$indexId,
                'value' => 1
            )
        ));

        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
            'clientData' => array(
                'tid' =>$output,
                'item' => 'rank_rank',
            )
        ));

        return true;
    }

    /**
     * 排行榜信息
     * @param $userId
     * @param $reqTime
     * @return array
     * @throws SzException
     */
    public function flowerLevelRankList($userId,$reqTime) {
        $redis = SzDbFactory::get()->getDb(null, SzAbstractDb::DB_TYPE_REDIS);

        $lastMondayDate = $this->getLastMondayDate($reqTime);
        $lastRankCacheKey = GameConst::CACHE_KEY_FLOWER_RANK.$lastMondayDate;

        $mondayDate = $this->getMondayDate($reqTime);

        $rankCacheKey = GameConst::CACHE_KEY_FLOWER_RANK.$mondayDate;
        // 上周排名
        $lastRank = $redis->zRevRank($lastRankCacheKey,$userId);

        $lastRank = $lastRank === false ? -1 : ++$lastRank;

        // 本周排名
        $currentRank = $redis->zRevRank($rankCacheKey,$userId);
        $currentRank = $currentRank ===  false ? -1 : ++$currentRank;

        // 上周奖励是否领取
        $isReward = 0;
        $rewardCacheKey = GameConst::CACHE_KEY_FLOWER_RANK_REWARD_STATUS.$lastMondayDate;
        if ($redis->hGet($rewardCacheKey,$userId)) {
            $isReward = 1;
        }

        // 排行榜信息
        $data = $redis->zRevRange($rankCacheKey,0,99,true);
        $res = array(
            'rank' => array(),
            'isReward' => $isReward,
            'lastRank' => $lastRank,
            'currentRank' => $currentRank
        );
        if ($data) {
            foreach ($data as $uId=>$number) {
                $res['rank'][] = ActivityService::get()->getUserInfo($uId,$number);
            }
        }
        return $res;
    }
}
